package icasue.base.register;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;

import javax.validation.constraints.NotNull;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2021/11/30 上午11:10
 * @UpdateDate:
 * @Description: ICasuePlugin 公共实例注册抽象接口，通过SPI的方式加载并执行.
 */
public abstract class ICasuePluginsRegister<ConfigProperties> implements ImportBeanDefinitionRegistrar {

    @NotNull
    protected BeanFactory beanFactory;
    @NotNull
    protected Environment environment;
    @NotNull
    protected ResourceLoader resourceLoader;
    @NotNull
    protected ClassLoader classLoader;

    protected ConfigProperties configProperties;

    /**
     * 读取环境变量配置的前缀.
     * @return
     */
    public abstract String environmentPropertiesPrefix();

    /**
     * 读取环境变量映射的JavaType.
     * @return
     */
    public abstract Class<ConfigProperties> environmentPropertiesType();


    /**
     * 注册的前置逻辑.
     * @return
     */
    protected void previousRegister(){

    }

    /**
     * Check逻辑, 返回值用于控制是否执行注册.
     * @return
     */
    @NotNull
    protected Boolean checkRegister(){
        return Boolean.TRUE;
    }

    /**
     * 成功注册后的执行逻辑.
     */
    protected void  postRegister(){

    }

    /**
     * 可重写排序值，控制加载顺序.
     * @return
     */
    protected Integer order(){
        return 1;
    }


    @Override
    public final void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry,
                                        BeanNameGenerator importBeanNameGenerator) {
        registerBeanDefinitions(importingClassMetadata, registry);
    }

    final void setEnvironmentProperties(ConfigProperties configProperties){
        this.configProperties = configProperties;
    }

    final void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    final void setEnvironment(Environment environment) {
        this.environment = environment;
    }
    final void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
    final void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }
}
